package com.littleHan.brushQuestions.web.userCenter.service.impl;

import com.littleHan.brushQuestions.exception.FailedToDeleteException;
import com.littleHan.brushQuestions.exception.FailedToLoadException;
import com.littleHan.brushQuestions.exception.FailedToUpdateException;
import com.littleHan.brushQuestions.exception.FailedToUploadException;
import com.littleHan.brushQuestions.web.start.dao.*;
import com.littleHan.brushQuestions.web.start.pojo.*;
import com.littleHan.brushQuestions.web.userCenter.dao.UserCenterDao;
import com.littleHan.brushQuestions.web.userCenter.pojo.Pagination;
import com.littleHan.brushQuestions.web.userCenter.pojo.vo.NoticeContentVo;
import com.littleHan.brushQuestions.web.userCenter.pojo.vo.TopicCollectAndTopicVo;
import com.littleHan.brushQuestions.web.userCenter.pojo.vo.TopicCommentVo;
import com.littleHan.brushQuestions.web.userCenter.service.UserCenterService;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.*;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;
import org.apache.commons.io.FilenameUtils;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserCenterServiceImpl implements UserCenterService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private UserRoleDao userRoleDao;

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private RolePermissionDao rolePermissionDao;

    @Autowired
    private PermissionDao permissionDao;

    @Autowired
    private UserCenterDao userCenterDao;

    @Value("${minio.enpoint}")
    String enpoint;

    @Value("${minio.username}")
    String username;

    @Value("${minio.password}")
    String password;

    private static final int FLAG = 1;

    @Override
    public List<Permission> getNavigationBar(String userId) throws FailedToLoadException {
        //根据userId去role表获取角色
        List<UserRole> userRoleList = userRoleDao.getRoleByUserId(userId);
        //根据取得的roleId去role表里获得角色信息
        List<Role> roleList = roleDao.getRoleById(userRoleList);
        //根据roleId去角色权限表获得其权限id
        List<RolePermission> rolePermissionList = rolePermissionDao.getRolePermissionByRoleId(roleList);
        //根据permissionId去权限表获取
        List<Permission> permissionList = permissionDao.getPermissionById(rolePermissionList);
        System.out.println("!!!" + permissionList);
        //String id=null;
        List<String> idList = new ArrayList<>();
        for (Permission p : permissionList) {
            if ("userCenter".equals(p.getCode())) {
                idList.add(p.getId());
                //id=p.getId();
            }
        }
        if (!idList.isEmpty()) {
            List<Permission> navigationBarList = userCenterDao.getNavigationBar(idList);
            /*for(Permission p:navigationBarList){
                System.out.println(p.getName());
            }*/
            return navigationBarList;
        } else {
            throw new FailedToLoadException("加载导航栏失败");
        }
    }

    @Override
    public GeneralUser getMyInfo(String userId) throws FailedToUploadException {
        GeneralUser generalUser = userCenterDao.getGeneralUserInfo(userId);
        if (generalUser == null) {
            throw new FailedToUploadException("获取个人资料失败");
        }
        return generalUser;
    }

    @Override
    @Transactional(rollbackFor = {FailedToLoadException.class})
    public void editUserInfo(String userId, GeneralUser generalUser) throws FailedToLoadException {
        int record = userCenterDao.editUserInfo(userId, generalUser);
        if (record < FLAG) {
            throw new FailedToLoadException("修改个人资料失败");
        }
    }

    @Override
    public String uploadIcon(String userId, MultipartFile file) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, FailedToUpdateException {
        String iconUrl = uploadToMinio(file, userId, "bq-icon");
        return iconUrl;
    }

    public String uploadToMinio(MultipartFile file, String userId, String bucket) throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, FailedToUpdateException {

        StringBuilder stringBuilder = new StringBuilder();
        //获取文件后缀名
        String suffix = FilenameUtils.getExtension(file.getOriginalFilename());
        //文件名为用户id+后缀名
        stringBuilder.append(userId).append(".").append(suffix);
        // 创建minio客户端
        MinioClient minioClient = MinioClient.builder()
                .endpoint(enpoint)
                .credentials(username, password)
                .build();
        // 添加上传参数
        PutObjectArgs args = PutObjectArgs.builder()
                //.object(file.getOriginalFilename())
                .object(stringBuilder.toString())
                .bucket(bucket)
                .contentType(file.getContentType())
                .stream(file.getInputStream(), file.getSize(), 0)
                .build();
        // 上传
        minioClient.putObject(args);
        String result = "/" + bucket + "/" + stringBuilder.toString();
        //将图片路径保存到数据库中

        if (userCenterDao.updateUserIcon(result, userId)!=1) {
            throw new FailedToUpdateException("上传头像失败");
        }
        return result;
    }

    @Override
    public Map<String, Object> getUserCollectTopicList(String userId, Pagination pagination) throws FailedToLoadException {
        Map<String, Object> map = new HashMap<>();
        //获取收藏总数量
        int result = userCenterDao.getUserCollectTopicListNum(userId);
        if (result < 1) {
            map.put("message", "用户还没有收藏的题目");
            map.put("total", result);
            return map;
        }
        //分页查询
        List<TopicCollectAndTopicVo> list = userCenterDao.getTopicCollectByUserId(userId, pagination);
        if (list.isEmpty()) {
            throw new FailedToLoadException("获取收藏题目失败");
        }
        for (TopicCollectAndTopicVo tct : list) { //获取题目数量
            tct.setCollectNum(userCenterDao.getCollectNum(tct.getTopicId()));
            tct.setCommentNum(userCenterDao.getCommentNum(tct.getTopicId()));
        }
        map.put("message", "用户还没有收藏的题目");
        map.put("total", result);
        map.put("list", list);
        return map;
    }

    @Override
    @Transactional(rollbackFor = {FailedToDeleteException.class})
    public void cancelTopicByCollectId(String id) throws FailedToDeleteException {
        int deleteResult = userCenterDao.cancelTopicByCollectId(id);
        if (deleteResult < 1) {
            throw new FailedToDeleteException("取消收藏题目失败");
        }
    }

    @Override
    public Map<String, Object> getUserAllComment(int pageNo, int pageSize, String userId) throws FailedToLoadException {
        //根据用户id获取所有评论以及题目（进行分页）
        List<TopicCommentVo> topicCommentVoList = userCenterDao.getUserAllComment(userId, pageNo, pageSize);
        Map<String, Object> map = new HashMap<>();
        map.put("commentAndTopicList", topicCommentVoList);
        //获取总数量
        int total = userCenterDao.getUserAllCommentNum(userId);
        map.put("total", total);
        return map;
    }

    @Override
    @Transactional(rollbackFor = {FailedToDeleteException.class})
    public void deleteMyComment(String id) throws FailedToDeleteException {
        int deleteResult = userCenterDao.deleteMyComment(id);
        if (deleteResult != 1) {
            throw new FailedToDeleteException("删除失败");
        }
    }

    @Override
    public Map<String, Object> getUserNotice(Pagination pagination, String userId) {
        List<NoticeContentVo> noticeContentVoList = userCenterDao.getNotice(userId, pagination.getPageNo(), pagination.getPageSize());
        int total = userCenterDao.getNoticeNum(userId);
        Map<String, Object> map = new HashMap<>();
        map.put("noticeContentVoList", noticeContentVoList);
        map.put("total", total);
        return map;
    }

    @Override
    public void setNoticeIsCheck(String id) throws FailedToUpdateException {
        int result = userCenterDao.updateIsRead(id);
        if (result != 1) {
            throw new FailedToUpdateException("消息已读失败");
        }
    }
}
